module AbsRust where

import qualified Data.Map as Map

type Position = String
type Error = String

type Id = String
type DefVars = [(Id,Path)]
data FunIdent = Fun Id Int
    deriving (Eq,Ord,Show)
   
type Path = [Id]

data FunInfo = FI [Parameter] Type Int Path
   | FErr
  deriving (Eq,Ord,Show)

data VarInfo = VVar Type Path
   | VConst Type Path
   | VStatic Type (RExpr,Type) Path
   | VPar Modality Type Path
   | VErr
  deriving (Eq,Ord,Show)

data Program =
   Prog [Item] Error
  deriving (Eq,Ord,Show)

data Item =
   IFun Id [Parameter] Type (Block,Type)
 | IStat Id Type (RExpr,Type)
  deriving (Eq,Ord,Show)

data Var =
   Var Id Error
 | VTup [Var]
  deriving (Eq,Ord,Show)

data Parameter = Param {
   pmdlt :: Modality,
   pvar :: Var,
   ptype :: Type
   }
  deriving (Eq,Ord,Show)

data Attribute =
   AConst
 | AMut
  deriving (Eq,Ord,Show)

data Modality =
   Constant
 | Value
 | Reference
  deriving (Eq,Ord,Show)

data Stmt =
   Let Attribute Var Type (Maybe (RExpr,Type))
 | SItem Item
 | RExprStmt (RExpr,Type)
  deriving (Eq,Ord,Show)

data RExpr =
   Assgn AssignmentOp (RExpr,Type) (RExpr,Type)
 | InfixOp InfixOp (RExpr,Type) (RExpr,Type)
 | UnaryOp UnaryOp (RExpr,Type)
 | FCall Id [(RExpr,Type)]
 | Const Const
 | LExpr (LExpr,Type)
 | Ref (LExpr,Type)
 | Cast Type (RExpr,Type)
 | Coertion Type Type (RExpr,Type)
 | TRExpr [(RExpr,Type)]
 | ArrRExpr [(RExpr,Type)]
 | Jmp JumpRExpr
 | Sel (IfRExpr, Type)
 | Iter IterRExpr
 | REBlk (Block,Type)
  deriving (Eq,Ord,Show)

data InfixOp = ArithOp ArithOp | RelOp RelOp | BoolOp BoolOp
  deriving (Eq,Ord,Show)
  
data ArithOp = Add | Sub | Mul | Div | Mod | Pow
  deriving (Eq,Ord,Show)
 
data BoolOp = Or | Xor | And
  deriving (Eq,Ord,Show)
  
data RelOp = Eq | NEq | Lt | LtE | Gt | GtE
  deriving (Eq,Ord,Show)

data UnaryOp = Not | Neg
  deriving (Eq,Ord,Show)

data Const = Bool Bool | Char Char | Float Double | Int Int | String String  | Unit
  deriving (Eq,Ord,Show)

data AssignmentOp = Assign | AssgnArith ArithOp | AssgnBool BoolOp
  deriving (Eq,Ord,Show)

data LExpr =
   Deref (RExpr,Type)
 | ArrayEl (LExpr,Type) (RExpr,Type)
 | SId Id Error
  deriving (Eq,Ord,Show)

data JumpRExpr =
   Break
 | Continue
 | RetExp (RExpr,Type)
  deriving (Eq,Ord,Show)

data Block =
   Block [Stmt] (RExpr,Type)
  deriving (Eq,Ord,Show)

data IfRExpr =
   IfNoElse (RExpr,Type) (Block,Type)
 | IfElse (RExpr,Type) (Block,Type) (ElseBlock,Type)
  deriving (Eq,Ord,Show)

data ElseBlock =
   EBlk (Block,Type)
 | EIf (IfRExpr,Type)
  deriving (Eq,Ord,Show)

data IterRExpr =
   While (RExpr,Type) (Block,Type)
 | Loop (Block,Type)
  deriving (Eq,Ord,Show)

data Type =
   BasicType BasicType
 | Pointer Type
 | Array (Maybe Int) Type
 | Tuple [Type]
 | TErr String
  deriving (Eq,Ord,Show)

data BasicType =
   BTChar
 | BTInt
 | BTFloat
 | BTString
 | BTBool
 | BTUnit
  deriving (Eq,Ord,Show)

type PC = Int
type Code = Map.Map PC LabInst
type LabInst = ((Maybe Label),Instruction)

data Address = AVar Id
 | Temp Int 
 | Cnst Const 
   deriving (Eq,Ord,Show)

data Label = L Int
	| F FunIdent (Maybe Int)
	| N
    deriving (Eq,Ord,Show)

data Instruction = AssBin InfixOp Address Address Address
	|AssUn UnaryOp Address Address
	|Copy Address Address
   |CastOp Type Address Address
	|Goto Label
	|If Address Label
	|IfFalse Address Label
	|IfRel RelOp Address Address Label
	|Call Address Label
	|RetVoid
	|Ret Address
	|Par Address 
	|AEl Address Address Address
	|AssAEl Address Address Address
	|AssRef Address Address
	|AssDeref Address Address
	|AssVtoP Address Address
	|Noop
      deriving (Eq,Ord,Show)
